//
//  KKNetWorking.swift
//  JGTProject
//
//  Created by ifly on 2017/7/18.
//  Copyright © 2017年 szy. All rights reserved.
//http://www.jianshu.com/p/874ceab0030a
//http://www.jianshu.com/p/903b678d2d3f //af 的用法介绍4.4的

import UIKit
import Alamofire


class NetWork: NSObject {
    
    
    ///MARK:采用自己写的进行网络请求
    class func postApi(_ url:String,
                       withParameters parameters:NSDictionary,
                       successBlock success:@escaping (_ object:NSDictionary)->Void,
                       errorBlock error:@escaping (_ errorString:String)->Void) -> Void{
        
//        print("url = \(url) \nparameters = \n\(parameters.toJosnString())")
        KKNetWorking.startInstance.postJsonData(url, parameters: parameters, successResult: { (jsonDate) in
            let newJsonData = jsonDate as? NSDictionary

            if newJsonData != nil{
//                print("请求结果:\n\(newJsonData!.toJosnString())")

                if newJsonData!.object(forKey: "code") as! String == "200" {
                    success(newJsonData!)
                    
                }else{
                    error(newJsonData!.object(forKey: "msg") as! String)
                }
                
            }
        }) {
             error("网络请求错误!")
        }
        
    }
    
    
    class func postAF(_ url:String,
                       parameters:Dictionary<String, Any>,
                       successCompletion:@escaping(_ object:Any) -> Void,
                       errorCompletion:@escaping(Error) -> Void) -> Void{
    
        Alamofire.request("\(url)", method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON { responseJsonDate in
            
            debugPrint(responseJsonDate)
            
            if let json = responseJsonDate.value {
                successCompletion(json)
            }
            if let error = responseJsonDate.result.error{
                debugPrint(error)
                errorCompletion(error)
            }
            
            }.responseString { (responseString) in
//              debugPrint("responseString: \(responseString)")
        }
        
    }
    
}

extension NSDictionary{
    
    public func toJosnString() -> String{
        
        if (!JSONSerialization.isValidJSONObject(self)) {
            debugPrint("无法解析出JSONString")
            return ""
        }
        let data : NSData! = try? JSONSerialization.data(withJSONObject: self, options:.prettyPrinted) as NSData!
        let JSONString = NSString(data:data as Data,encoding: String.Encoding.utf8.rawValue)
        return JSONString! as String
    }
    
    
    public func toJosnStringA() -> String{
        
        if (!JSONSerialization.isValidJSONObject(self)) {
            debugPrint("无法解析出JSONString")
            return ""
        }
        let data : NSData! = try? JSONSerialization.data(withJSONObject: self, options:JSONSerialization.WritingOptions(rawValue: 0)) as NSData!
        let JSONString = NSString(data:data as Data,encoding: String.Encoding.utf8.rawValue)
        return JSONString! as String
        
    }
    
}
//数据接收成功的代码块
typealias KKSuccussCompletion = (_ jsonData:Any)->Void
typealias KKFailureCompletion = ()->Void

class KKNetWorking: NSObject {
    
    var onSuccess:KKSuccussCompletion?
    var onFailure :KKFailureCompletion?
    
    
    internal static let startInstance = KKNetWorking.init() //这个位置使用 static，static修饰的变量会懒加载

    var responseData = NSMutableData()
    
    private func custemURLRequest(_ httpMethod:String,urlString:String,parameters:NSDictionary) -> NSMutableURLRequest {
        
//        print(urlString)
//        print(parameters.toJosnString())
        
        let url: NSURL = NSURL(string: urlString)!
        let request: NSMutableURLRequest = NSMutableURLRequest(url: url as URL)
        request.httpMethod = httpMethod
        request.httpBody = parameters.toJosnString().data(using: String.Encoding.utf8)
        
        return request;
    }


    /// post 请求 通过httpBody
    ///
    /// - Parameters:
    ///   - urlString: 请求地址
    ///   - parameters: 请求参数 NSDictionary 类型
    ///   - successResult: 请求成功代码块
    ///   - failure: 请求失败
    public func postJsonData(_ urlString:String,
                             parameters:NSDictionary,
                             successResult:@escaping KKSuccussCompletion,
                             failure:@escaping KKFailureCompletion) -> Void {
        
        let request=self.custemURLRequest("POST", urlString: urlString, parameters: parameters)

        let session: URLSession = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)
        
        let dataTask: URLSessionTask = session.dataTask(with: request as URLRequest)
        
        dataTask.resume()
        
        self.onSuccess = successResult
        self.onFailure = failure
        
    }
    
    /// Get 请求 通过httpBody
    ///
    /// - Parameters:
    ///   - urlString: 请求地址
    ///   - parameters: 请求参数 NSDictionary 类型
    ///   - successResult: 请求成功代码块
    ///   - failure: 请求失败
    public func getJsonData(_ urlString:String,
                            parameters:NSDictionary,
                            successResult:@escaping KKSuccussCompletion,
                            failure:@escaping KKFailureCompletion) -> Void {
        
        let request=self.custemURLRequest("GET", urlString:  urlString, parameters: parameters)
        
        let session: URLSession = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)
        
        let dataTask: URLSessionTask = session.dataTask(with: request as URLRequest)
        
        dataTask.resume()
        
        self.onSuccess = successResult
        self.onFailure = failure
        
    }
    
    /// 上传图片 post 方式
    ///http://blog.csdn.net/xy_26207005/article/details/51564833 上传下载介绍
    /// - Parameters:
    ///   - urlString: 请求地址
    ///   - parameters: 请求参数 NSDictionary 类型
    ///   - img: 上传的图片
    ///   - successResult: 请求成功代码块
    ///   - failure: 请求失败
    public func upImage(_ urlString:String,
                        parameters:NSDictionary,
                        img:UIImage,
                        successResult:@escaping KKSuccussCompletion,
                        failure:@escaping KKFailureCompletion) -> Void{
        
        let request=self.custemURLRequest("POST", urlString: urlString, parameters:parameters)

        request.addValue("image/jpeg", forHTTPHeaderField: "Content-Type")
        request.addValue("text/html", forHTTPHeaderField: "Accept")
        
        let imgData = UIImageJPEGRepresentation(img, 1.0)
        let session: URLSession = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)

        let upDataTask:URLSessionUploadTask = session.uploadTask(with: request as URLRequest, from: imgData!)
        upDataTask.resume()

        self.onSuccess = successResult
        self.onFailure = failure
    }
    
    public func download(_ urlString:String,
                         successResult:@escaping KKSuccussCompletion,
                         failure:@escaping KKFailureCompletion) -> Void{
        
        let url: NSURL = NSURL(string: urlString)!
        let request: NSMutableURLRequest = NSMutableURLRequest(url: url as URL)
        let session: URLSession = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)
        
        let downloadTask:URLSessionDownloadTask = session.downloadTask(with: request as URLRequest)
        downloadTask.resume()
        
        self.onSuccess = successResult
        self.onFailure = failure
    }

    

    
    func getDictionaryFromJSONString(jsonString:String) ->NSDictionary{
        
        let jsonData:Data = jsonString.data(using: .utf8)!
        
        let dict = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
        if dict != nil {
            return dict as! NSDictionary
        }
        return NSDictionary()
        
        
    }
}




extension KKNetWorking:URLSessionDelegate
{
    
    
    //1.接收到服务器响应的时候调用该方法
    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
        
        self.responseData = NSMutableData()
        //在该方法中可以得到响应头信息，即response
        //注意：需要使用completionHandler回调告诉系统应该如何处理服务器返回的数据
        //默认是取消的
        /*
         NSURLSessionResponseCancel = 0,        默认的处理方式，取消
         NSURLSessionResponseAllow = 1,         接收服务器返回的数据
         NSURLSessionResponseBecomeDownload = 2,变成一个下载请求
         NSURLSessionResponseBecomeStream        变成一个流
         */
        
        completionHandler(URLSession.ResponseDisposition.allow)
    }
    
    
    //2.接收到服务器返回数据的时候会调用该方法，如果数据较大那么该方法可能会调用多次
    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        //拼接服务器返回的数据
        self.responseData.append(data)
        
    }
    
    //3.当请求完成(成功|失败)的时候会调用该方法，如果请求失败，则error有值
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        
        if (error == nil) {
            do {
                
                let dict  = try JSONSerialization.jsonObject(with: self.responseData as Data, options: .allowFragments)
                
                if self.onSuccess != nil {
                    self.onSuccess!(dict)
                }
                
            } catch {
                let daString:NSString = NSString.init(data: self.responseData as Data, encoding: String.Encoding.utf8.rawValue)!
                debugPrint("Data to json 失败! data转String =  \(daString)")
                if self.onFailure != nil{
                    self.onFailure!()
                }
            }
            
        }else{
            debugPrint("error = \(error!)")
            
            if self.onFailure != nil {
                self.onFailure!()
            }
        }
    }
    //    上传数据的代理方法
    func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
        
    }
    //    下载的代理方法
    public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){
        
        let cacheDirectory = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).last! as NSString
        let newCacheDirectory =  cacheDirectory.appendingPathComponent("KKCACHES")
        let fileManager = FileManager.default
        
        do {
            try fileManager.moveItem(at: location, to: URL.init(fileURLWithPath: newCacheDirectory))
        } catch  {
            print("移动文件失败")
        }
        
    }
    
    // 下载过程中 会多次调用, 记录下载进度
    public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64){
        
    }
    // 当调用恢复下载的时候 触发的代理方法 [_downLoadTask resume]
    public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64){
        
    }
    
    
}




















